
from django.views import View
from django.http import HttpResponse, JsonResponse
from django_redis import get_redis_connection
from huamei_mall.libs.captcha.captcha import captcha
from celery_tasks.sms.tasks import ccp_send_sms_code
import logging
logger = logging.getLogger('django')
import random
from django import http
from huamei_mall.libs.yuntongxun.ccp_sms import CCP
class ImageCodeView(View):
    '''返回图形验证码的类视图'''

    def get(self, request, uuid):
        '''
        生成图形验证码, 保存到redis中, 另外返回图片
        :param request:请求对象
        :param uuid:浏览器端生成的唯一id
        :return:一个图片
        '''
        # 1.调用工具类 captcha 生成图形验证码

        text, image = captcha.generate_captcha()

        # 2.链接 redis, 获取链接对象
        redis_conn = get_redis_connection('verify_code')

        # 3.利用链接对象, 保存数据到 redis, 使用 setex 函数
        # redis_conn.setex('<key>', '<expire>', '<value>')
        redis_conn.setex('img_%s' % uuid, 300, text)

        # 4.返回(图片)
        return HttpResponse(image,
                            content_type='image/jpg')

class SMSCodeView(View):

    def get(self, request, mobile):
        '''接收参数, 检验, 发送短信验证码'''

        # 额外增加的功能: 避免频繁发送短信验证码
        # 0. 从redis中获取60s保存的信息
        redis_conn = get_redis_connection('verify_code')

        flag = redis_conn.get('flag_%s' % mobile)

        # 0.1 判断该值是否存在, 如果不存在, 进行下面的步骤, 如果存在, 返回
        if flag:
            return JsonResponse({'code': 400,
                                 'errmsg': "请不要频繁发送短信验证码"})

        # 1.接收查询字符串参数
        image_code_client = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')

        # 2.总体检验(查看参数是否为空)
        if not all([image_code_client, uuid]):
            return JsonResponse({'code':400,
                                 'errmsg':"必传参数不能为空"})

        # 3.链接redis, 获取redis的链接对象
        # 这里的步骤挪到了上面

        # 4.从redis中取出图形验证码
        image_code_server = redis_conn.get('img_%s' % uuid)

        # 5.判断服务端的图形验证码是否过期, 如果过期, return
        if image_code_server is None:
            return JsonResponse({'code':400,
                                 'errmsg':"图形验证码过期"})

        # 6.删除redis中图形验证码
        try:
            redis_conn.delete('img_%s' % uuid)
        except Exception as e:
            logger.info(e)

        # 7.对比前后端的图形验证码
        if image_code_client.lower() != image_code_server.decode().lower():
            return JsonResponse({'code': 400,
                                 'errmsg': "输入的图形验证码出错"})

        # 8.随机生成6为的短信验证码
        sms_code = '%06d' % random.randint(0, 999999)

        # 9.打印短信验证码
        logger.info(sms_code)

        # 创建redis管道:
        pl = redis_conn.pipeline()

        # 10.把短信验证码保存到redis
        pl.setex('sms_%s' % mobile, 300, sms_code)

        pl.setex('flag_%s' % mobile, 60, 1)

        # 执行管道:
        pl.execute()

        # 11.调用容联云, 发送短信验证码
        # CCP().send_template_sms(mobile, [sms_code, 5], 1)
        # 添加一个提示celery抛出任务的提醒:
        #
        ccp_send_sms_code.delay(mobile, sms_code)

        # 12.返回json
        return JsonResponse({'code': 0,
                             'errmsg': "ok"})



# class SMSCodeView(View):
#
#     def get(self, reqeust, mobile):
#
#         # 将这句话提到前面最开始的位置:
#         redis_conn = get_redis_connection('verify_code')
#         # 进入函数后, 先获取存储在 redis 中的数据
#         send_flag = redis_conn.get('send_flag_%s' % mobile)
#         # 查看数据是否存在, 如果存在, 说明60s没过, 返回
#         if send_flag:
#             return http.JsonResponse({'code': 400,
#                                       'errmsg': '发送短信过于频繁'})
#
#         # 如果过了, 在执行下面的代码:
#
#         image_code_client = reqeust.GET.get('image_code')
#         uuid = reqeust.GET.get('image_code_id')
#
#         if not all([image_code_client, uuid]):
#             return http.JsonResponse({'code': 400,
#                                       'errmsg': '缺少必传参数'})
#
#         image_code_server = redis_conn.get('img_%s' % uuid)
#         if image_code_server is None:
#             return http.JsonResponse({'code': 400,
#                                       'errmsg': '图形验证码失效'})
#
#         try:
#             redis_conn.delete('img_%s' % uuid)
#         except Exception as e:
#             logger.error(e)
#
#         image_code_server = image_code_server.decode()
#         if image_code_client.lower() != image_code_server.lower():
#             return http.JsonResponse({'code': 400,
#                                       'errmsg': '输入图形验证码有误'})
#
#         sms_code = '%06d' % random.randint(0, 999999)
#         logger.info(sms_code)
#
#         pl = redis_conn.pipeline()
#
#
#         pl.setex('sms_%s' % mobile, 300, sms_code)
#
#         # 往 redis 中写入一个数据, 写入什么不重要, 时间重要
#         # 我们给写入的数据设置为60s,如果过期,则会获取不到.
#         pl.setex('send_flag_%s' % mobile, 60, 1)
#
#         pl.execute()
#
#
#
#         # 原来的写法:
#         # CCP().send_template_sms(mobile, [sms_code, 5], 1)
#
#         # 改为现在的写法, 注意: 这里的函数,调用的时候需要加: .delay()
#         # .delay()　
#         ccp_send_sms_code.delay(mobile, sms_code)
#
#         return http.JsonResponse({'code': 0,
#                                   'errmsg': '发送短信成功'})